/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * NodesPanel.java
 *
 * Created on Apr 17, 2009, 12:57:20 PM
 */
package view.panels.analytical;

import controller.Controller;
import controller.GraphController;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import jgf.beans.GraphBean;
import jgf.beans.NodeBean;
import jgf.exceptions.attribute.BadAttributeListException;
import jgf.exceptions.node.DuplicatedNodeException;
import jgf.exceptions.node.UnexistentNodeException;

/**
 *
 * @author Biddu
 */
public class NodesPanel extends javax.swing.JPanel {

    private GraphBean graph;
    private Integer rowcount = 0;
    private DefaultTableModel tNodeModel;
    private final int ATTRIBUTE_ID = 1;
    private final int DELETE_ID = 2;
    private Integer selectedRowID;
    private TreeMap<Integer, Integer> nodeRows;

    /** Creates new form NodesPanel */
    public NodesPanel() {
        nodeRows = new TreeMap<Integer, Integer>();
        initComponents();
    }
    private Controller controller;

    public void setController(Controller controller) {
        this.controller = controller;
    }

    void loadGraph(GraphBean graph) {
        this.graph = graph;
        this.syncOnLoad();
        this.setTableProperties();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        nodeAttribute = new javax.swing.JDialog();
        sourceCheckBox = new javax.swing.JCheckBox();
        sinkCheckBox = new javax.swing.JCheckBox();
        nodeAttrButton = new javax.swing.JButton();
        createNode = new javax.swing.JButton();
        nodesScrollPanel = new javax.swing.JScrollPane();
        nodesTable = new javax.swing.JTable();

        nodeAttribute.setTitle("Node Attributes");
        nodeAttribute.setModal(true);
        nodeAttribute.getContentPane().setLayout(new java.awt.GridBagLayout());

        sourceCheckBox.setText("Source");
        sourceCheckBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                sourceCheckBoxActionPerformed(evt);
            }
        });
        nodeAttribute.getContentPane().add(sourceCheckBox, new java.awt.GridBagConstraints());

        sinkCheckBox.setText("Sink");
        nodeAttribute.getContentPane().add(sinkCheckBox, new java.awt.GridBagConstraints());

        nodeAttrButton.setText("Okay");
        nodeAttrButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                nodeAttrButtonActionPerformed(evt);
            }
        });
        nodeAttribute.getContentPane().add(nodeAttrButton, new java.awt.GridBagConstraints());

        setLayout(new javax.swing.BoxLayout(this, javax.swing.BoxLayout.PAGE_AXIS));

        createNode.setText("Create Node");
        createNode.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                createNodeActionPerformed(evt);
            }
        });
        add(createNode);

        nodesTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "*", "Nodes", "Attributes", "Delete"
            }
        ));
        nodesScrollPanel.setViewportView(nodesTable);

        add(nodesScrollPanel);
    }// </editor-fold>//GEN-END:initComponents

	private void createNodeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_createNodeActionPerformed
		try {
			NodeBean n = new NodeBean();
			GraphController gc = this.controller.getGraphController(graph.getID());
			gc.insertNode(n);
		} catch (BadAttributeListException ex) {
			//TODO add exception handling code.
		}

	}//GEN-LAST:event_createNodeActionPerformed

    private void sourceCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_sourceCheckBoxActionPerformed
        // TODO add your handling code here:        
    }//GEN-LAST:event_sourceCheckBoxActionPerformed

    private void nodeAttrButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nodeAttrButtonActionPerformed
        try {
			nodeAttribute.setVisible(false);
			GraphController gc = this.controller.getGraphController(graph.getID());
			NodeBean node = new NodeBean();
			node.setId(nodeRows.get(selectedRowID));
			if (sourceCheckBox.isSelected()) {
				gc.setSource(node);
			} else {
				gc.unsetSource(node);
			}
			if (sinkCheckBox.isSelected()) {
				gc.setSink(node);
			} else {
				gc.unsetSink(node);
			}
		} catch (DuplicatedNodeException duplicatedNodeException) {
		} catch (UnexistentNodeException unexistentNodeException) {
		}

    }//GEN-LAST:event_nodeAttrButtonActionPerformed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton createNode;
    private javax.swing.JButton nodeAttrButton;
    private javax.swing.JDialog nodeAttribute;
    private javax.swing.JScrollPane nodesScrollPanel;
    private javax.swing.JTable nodesTable;
    private javax.swing.JCheckBox sinkCheckBox;
    private javax.swing.JCheckBox sourceCheckBox;
    // End of variables declaration//GEN-END:variables

    // <editor-fold defaultstate="collapsed" desc="Custom Code">
    public void insertNode(NodeBean node) {
        String defaultNodeName = "Node_";
        if (node.getLabel() == null || "".equalsIgnoreCase(node.getLabel())) {
            defaultNodeName = defaultNodeName + node.getId();
        } else {
            defaultNodeName = node.getLabel();
        }
        tNodeModel.insertRow(rowcount,
                new Object[]{"" + (rowcount + 1), defaultNodeName, "Modify", "X"});
        nodeRows.put(rowcount, node.getId());
        rowcount++;

    }

    public void deleteNode(NodeBean node) {
        TreeMap<Integer, Integer> tempNodes = new TreeMap<Integer, Integer>();
        Integer tempRowCount = 0;
        for (int a = 0; a < nodeRows.size(); a++) {
            if (node.getId() == nodeRows.get(a)) {
                selectedRowID = a;
            }
        }
        tNodeModel.removeRow(selectedRowID);

        for (int i = 0; i < rowcount; i++) {
            if (i != selectedRowID) {
                tempNodes.put(tempRowCount, nodeRows.get(i));
                tNodeModel.setValueAt(tempRowCount + 1, tempRowCount, 0);
                tempRowCount++;
            }
        }
        nodeRows = tempNodes;
        rowcount--;
    }

    public void setTableProperties() {
        int vColIndex = 2;
        TableColumn tcol2 = nodesTable.getColumnModel().getColumn(vColIndex);
        tcol2.setCellRenderer(new ButtonRenderer());
        tcol2.setCellEditor(new ButtonEditor(new JCheckBox(), ATTRIBUTE_ID));

        vColIndex = 3;
        TableColumn tcol3 = nodesTable.getColumnModel().getColumn(vColIndex);
        tcol3.setCellRenderer(new ButtonRenderer());
        tcol3.setCellEditor(new ButtonEditor(new JCheckBox(), DELETE_ID));
    }

    public void syncOnLoad() {
        tNodeModel = (DefaultTableModel) nodesTable.getModel();
        String defaultNodeName = "Node_";
        if (graph != null) {
            for (NodeBean node : graph.getNodes()) {

                String nodeName = defaultNodeName + node.getId();
                if (node.getLabel() == null || "".equals(node.getLabel())) {
                    nodeName = defaultNodeName + (rowcount + 1);
                } else {
                    nodeName = node.getLabel();
                }
                tNodeModel.insertRow(rowcount, new Object[]{"" + (rowcount + 1), nodeName, "Modify", "X"});
                nodeRows.put(rowcount, node.getId());
                rowcount++;
            }
        }
    }

    private class ButtonRenderer extends JButton implements TableCellRenderer {

        public ButtonRenderer() {
            setOpaque(true);
        }

        public Component getTableCellRendererComponent(JTable table, Object value,
                boolean isSelected, boolean hasFocus, int row, int column) {
            if (isSelected) {
                setForeground(table.getSelectionForeground());
                setBackground(table.getSelectionBackground());
            } else {
                setForeground(table.getForeground());
                setBackground(UIManager.getColor("Button.background"));
            }
            setText((value == null) ? "" : value.toString());
            return this;
        }
    }

    /**
     * @version 1.0 11/09/98
     */
    private class ButtonEditor extends DefaultCellEditor {

        protected JButton button;
        private String label;
        private boolean isPushed;
        private int buttonID;

        public ButtonEditor(JCheckBox checkBox, int id) {
            super(checkBox);
            button = new JButton();
            button.setOpaque(true);
            buttonID = id;
            button.addActionListener(new ActionListener() {

                public void actionPerformed(ActionEvent e) {
                    fireEditingStopped();
                }
            });
        }

        public void setButtonId(int id) {
            buttonID = id;
        }

        @Override
        public Component getTableCellEditorComponent(JTable table, Object value,
                boolean isSelected, int row, int column) {
            if (isSelected) {
                button.setForeground(table.getSelectionForeground());
                button.setBackground(table.getSelectionBackground());
            } else {
                button.setForeground(table.getForeground());
                button.setBackground(table.getBackground());
            }
            label = (value == null) ? "" : value.toString();
            button.setText(label);
            isPushed = true;
            selectedRowID = row;
            return button;
        }

        @Override
        public Object getCellEditorValue() {
            if (isPushed) {
                //
				NodeBean node = new NodeBean();
				node.setId(nodeRows.get(selectedRowID));
                if (buttonID == ATTRIBUTE_ID) {
                    if (graph.getSourceList().contains(graph.selectNode(nodeRows.get(selectedRowID)))) {
                        sourceCheckBox.setSelected(true);
                    } else {
                        sourceCheckBox.setSelected(false);
                    }
                    if (graph.getSinkList().contains(graph.selectNode(nodeRows.get(selectedRowID)))) {
                        sinkCheckBox.setSelected(true);
                    } else {
                        sinkCheckBox.setSelected(false);
                    }
                    nodeAttribute.setVisible(isPushed);
                } else if (buttonID == DELETE_ID) {
                    GraphController gc = controller.getGraphController(graph.getID());
					try {
						gc.deleteNode(node);
					} catch (UnexistentNodeException ex) {
						//TODO exception handling code
					}
                }
                //

                // System.out.println(label + ": Ouch!");
            }
            isPushed = false;
            return new String(label);
        }

        @Override
        public boolean stopCellEditing() {
            isPushed = false;
            return super.stopCellEditing();
        }

        @Override
        protected void fireEditingStopped() {
            try {
                super.fireEditingStopped();
            } catch (Exception e) {
            }
        }
    }
    // </editor-fold>
}
